﻿//
// *************************************************************************************
// WP-Framework
//
// Developed by 
// Lukas Kretschmar (lkretschmar.dev@bluewin.ch)
//
// Switzerland, Copyright (c) 2013 lkretschmar
// This content is released under the MIT License (http://opensource.org/licenses/MIT).
//     
// *************************************************************************************
//
//
			

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using KretschIT.WP_Fx.Testing;
using KretschIT.WP_Fx.EasyMoq.Test.Helpers.Objects;

namespace KretschIT.WP_Fx.EasyMoq.Test.IntegrationTests
{
    [TestClass]
    public class ActionTest
    {
        private IMock<ITestObject> mock;

        [TestInitialize]
        public void Init()
        {
            this.mock = Easy.Moq.Mock<ITestObject>();
        }

        [TestMethod]
        public void Test_Setup_Verify()
        {
            this.mock.Setup(i => i.Action());
            this.mock.Verify(i => i.Action(), Condition.Never());
        }

        [TestMethod]
        public void Test_Setup_Execute_Verify()
        {
            this.mock.Setup(i => i.Action());

            this.mock.Object.Action();

            this.mock.Verify(i => i.Action());
            this.mock.Verify(i => i.Action(), Condition.Once());
        }

        [TestMethod]
        public void Test_Setup_ExecuteX_Verify()
        {
            this.mock.Setup(i => i.Action());

            this.mock.Object.Action();
            this.mock.Object.Action();

            this.mock.Verify(i => i.Action(), Condition.AtLeastOnce());
            this.mock.Verify(i => i.Action(), Condition.Exactly(2));
        }

        [TestMethod]
        public void Test_Setup_WithArgument_Execute_Verify()
        {
            this.mock.Setup(i => i.Action("test"));

            this.mock.Object.Action("test");

            this.mock.Verify(i => i.Action("test"));
            this.mock.Verify(i => i.Action("test"), Condition.AtLeastOnce());
            this.mock.Verify(i => i.Action(Allow.Any<string>()), Condition.Once());
            this.mock.Verify(i => i.Action(Allow.Only<string>(s => s == "test")), Condition.Once());
        }

        [TestMethod]
        public void Test_Setup_WithArgument_Execute_Execute_Verify()
        {
            this.mock.Setup(i => i.Action("test"));

            this.mock.Object.Action("test");
            this.mock.Object.Action("test");
            this.mock.Object.Action("test");

            this.mock.Verify(i => i.Action("test"), Condition.Exactly(3));
            this.mock.Verify(i => i.Action(Allow.Any<string>()), Condition.Exactly(3));
            this.mock.Verify(i => i.Action(Allow.Only<string>(s => s == "test")), Condition.Exactly(3));
        }

        [TestMethod]
        public void Test_Setup_Any_Execute_Verify()
        {
            this.mock.Setup(i => i.Action(Allow.Any<string>()));

            this.mock.Object.Action("test");

            this.mock.Verify(i => i.Action(Allow.Any<string>()));
        }

        [TestMethod]
        public void Test_Setup_MultiArgument_Execute_Verify()
        {
            this.mock.Setup(i => i.Action("test", "test"));

            this.mock.Object.Action("test", "test");

            this.mock.Verify(i => i.Action("test", "test"));
            this.mock.Verify(i => i.Action("test", "test"), Condition.AtLeastOnce());
            this.mock.Verify(i => i.Action(Allow.Any<string>(), Allow.Any<string>()), Condition.Once());
            this.mock.Verify(i => i.Action(Allow.Only<string>(s => s == "test"), Allow.Only<string>(s => s == "test")), Condition.Once());

            this.mock.Verify(i => i.Action(Allow.Any<string>()), Condition.Never());
            this.mock.Verify(i => i.Action(Allow.Only<string>(s => s == "test")), Condition.Never());
        }

        [TestMethod]
        public void Test_Setup_Exception_Verify()
        {
            this.mock.Setup(i => i.Action("test")).Throws(new NotSupportedException());

            ExceptionAssert.Throws<NotSupportedException>(() =>
            {
                this.mock.Object.Action("test");
            });

            this.mock.Verify(i => i.Action("test"), Condition.Once());
            this.mock.Verify(i => i.Action(Allow.Any<string>()), Condition.Once());
        }
    }
}
